<template>
	<div class="map-view-public-data">


        <georeference :isPublic="!isPrivate" v-if="georeferenceShow"
            :uid="dataUid"></georeference>

		<div id="mapContainer"></div>

        <div id="mapOverLap" v-if="toggleMapSelect">
            <!-- 该元素用于响应@blur事件，无其他作用 -->
        </div>

        <div class="zoom-container">
            <div class="map-icon" @click="zoomIn"><i class="iconfont icon-plus"></i></div>
            <div class="zoom-split"></div>
            <div class="map-icon" @click="zoomOut"><i class="iconfont icon-minus"></i></div>
        </div>

        <div class="map-select-container"  v-if="hasMapSelecter" tabindex="5" v-focus="toggleMapSelect" @blur="closeMapSelect()">

            <div class="map-icon" @click="toggleSelect()"><i class="iconfont icon-map"></i></div>

            <div class="map-select-content" v-show="toggleMapSelect">
                <div class="base-map-item" v-for="(map,key) in baseMapList" :key="key" @click="setBaseMap(key)" :class="{selected:key === currentMap}">
                    <div class="map-thumb" :style="{ backgroundImage: 'url(\''+map.thumb+'\')' }"><i class="iconfont icon-success-fill map-selected"></i></div>
                    <div class="map-label">{{map.label}}</div>
                </div>
            </div>
        </div>

        <transition name="wait-fade">
            <div class="eraser-container" v-show="waiting">
                <div class="map-icon"><i class="iconfont icon-loading spin"></i></div>
            </div>
        </transition>

        <div id="result" class="result" ref="queryResult" v-show="showResult">
            <div class="result-container" >
                <div class="result-title">
                    <div class="title-content">属性信息</div>
                    <div id="closeButton" class="title-close"><i class="iconfont icon-close"></i></div>
                </div>

                <div class="result-content">
                    <div class="hide-scroll">

                        <div v-for="(result, idx) in queryResults" :key="idx" class="result-list">
                            <div class="result-key">{{result.key}}</div>
                            <div class="result-val">{{result.val}}</div>
                        </div>

                    </div>
                </div>

            </div>
            <div class="arrow"></div>
        </div>

	</div>
</template>

<script>

    import axios from 'axios'
	import Bus from '../../utils/event_bus'
    import constant from '@/config/constant.js'
	import GMessageBox from '@/components/common/g-message-box'
	import Georeference from '../data/georeference'
	import GButton from '@/components/common/g-button'
    import 'geohey-javascript-sdk/dist/lib/g.css'
    import G from 'geohey-javascript-sdk'
    import 'geohey-javascript-sdk/dist/lib/g-canvas.min.js'
    import qs from 'qs'
    import map from '../../../static/js/config.js'


    import { dashboard as dashboardAPI } from '@/api'

    var axiosInstance = axios.create({
        headers: {'Content-Type': 'application/x-www-form-urlencoded' }
    });

    export default {

        name: 'map-view',

		components: {
			Georeference,
			GMessageBox,
			GButton
		},

		props: {
			previewData: {
                type: Object,
                default: {}
            },
            isPrivate: Boolean,
            dataType: String
        },

        data: function() {
            return {
				dataUid: null,
                geomType: null,
                map:'',
                waiting: false,
                constant: constant,
                hasMapSelecter: true,
                toggleMapSelect: false,
				spatializeOrNot: true,

                baseMapLayer:'',
                //currentMap: 'googleRoad',
                currentMap: 'auto',
                baseMapList: map.baseMapList,

                vizId:'',
                dataLayer:'',

                defaultGraphics:'',
                defaultHtmlLayer:'',
                htmlLayerMark:'',
                queryResults:[],
                showResult: false,

				georeferenceShow: false,

                isMobel: !!window.navigator.userAgent.match( /(iPhone|iPod|iPad|Android|ios)/i ),
                role: this.$root.geohey.user.role || '', 
            }
        },

        directives: {
            focus: {
                componentUpdated: function (el, {value}) {
                    if (value) {
                        el.focus();
                    }
                }
            }
        },

		created() {
			Bus.$on('georeference-cancel', () => {
				this.georeferenceShow = false;
			});

			Bus.$on('georeference-success', () => {
				this.georeferenceShow = false;
                this.$message.success('空间化成功');
                this.initDataViz(this.dataUid);
                return true;
            });
            
            if (this.previewData && this.previewData.uid) {
                this.dataUid = this.previewData.uid;
			}

			this.geomType = this.previewData.geometryType;

		},

        mounted() {
            this.initMap();
            
            if(this.dataType === 'imagery'){
                this.initImagery( this.dataUid, this.isPrivate, this.previewData.bandsCount );
                return;
            }
            if (!this.previewData.convertEnd && this.isPrivate) {
				this.showGeoreferenceConfirm();
				return;
			}

			this.initDataViz(this.dataUid);

        },

        methods: {

			/**
			 * 初始化地图
			 */
            initMap: function() {

                let self = this;
                let map;
                let baseMapLayer;
                let baseMap = this.baseMapList[this.currentMap];

                map = new G.Map('mapContainer', {
                    maxRes: 160000,
                    minRes: 0.14929107086945 / 2,
                    scrollPage: true,
                    wrap: true,
                    recordStatus: false,
                    pinchRotate: false,
                    continuouslyZoom: false,
                    initStatus: {
                        center: [12187652.353839781, 4230951.10429896],
                        res: 4891.96981025
                    },
                    hideLogo: true
                });

                baseMapLayer = new G.Layer.Tile(baseMap.url, {
                    cluster: baseMap.cluster
                });

                baseMapLayer.addTo(map);

                if (self.previewData.extent) {
                    map.zoomExtent(JSON.parse(self.previewData.extent), {
                        ignoreAnim: true
                    });
                }

                self.baseMapLayer = baseMapLayer;
                self.defaultGraphics = new G.Layer.Graphic();
                self.defaultHtmlLayer = new G.Layer.Html();
                self.defaultGraphics.addTo(map);
                self.defaultHtmlLayer.addTo(map);
                self.map = map;

                let clickOption = self.isMobel ? 'touchend' : 'click';

                self.map.addListener(clickOption, (e)=>{

                    if (!this.waiting) {
                        self.query(e);
                    }

                });

            },

			/**
			 * 数据上图
			 */
            initDataViz: async function(dataUid){
                
                let vizConfig = await this.createVizOptions(dataUid);
                
                if(this.$store.state.data_nav_key == 'private-data'){
                    let dom = document.querySelector('.private-upload-res');
                    if(!dom.classList.contains('active')){
                        vizConfig.dataType = 'public';
                    }
                }
                
                let params = {
                    configJson: JSON.stringify(vizConfig)
                };
                
                axiosInstance.get(`/s/dataviz/config`, {params: params})
                .then((res)=>{

                    if(res.data.code !== 0){
                        console.log('可视化失败');
                        return true;
                    }

                    this.vizId = res.data.data.vizId;
                    return true;

                })
                .catch((err)=>{
					console.log(err);
                    throw err;
                });

            },

			/**
			 * 初始化可视化选项
			 * @param object vizData
			 */
            createVizOptions: async function (dataUid){
				let defaultVizConfig = this.constant.defaultVizConfig;

				if (dataUid && this.geomType) {

					let config = this.constant.defaultVizConfig[this.geomType];
					config.dataUid = this.dataUid;
                    config.dataType = this.isPrivate ? 'private' : 'public';
                    
					return config;
				}

				let config = await axiosInstance.get(`/s/${this.isPrivate ? 'data' : 'public_data'}/${dataUid}/info`, {})
				.then((res) => {
					if (res.data.code !== 0) {
						this.$message.error('地图刷新失败，可尝试手动刷新页面');
						return;
					}

					let geomType = 'mpg';
					if (res.data.data && res.data.data.geomType) {
						geomType = res.data.data.geomType;
					}
					let config = defaultVizConfig[geomType];

					let dataInfo = res.data.data;
					config.dataUid = dataInfo.uid;
	                config.dataType = this.isPrivate ? 'private' : 'public';
					this.dataUid = dataInfo.uid;
					this.geomType = geomType;

	                return config;

				})
				.catch((err) => {
					console.log(err);
					this.$message.error('地图刷新失败，可尝试手动刷新页面');
					return;
				});

				return config;

            },

            query: function(e){
                let map = this.map;
                let ld = map.toMap([e.screenX - 4, e.screenY + 4]);
                let ru = map.toMap([e.screenX + 4, e.screenY - 4]);
                let uid = this.previewData.uid;
                let rect = [ld[0], ld[1], ru[0], ru[1]];
                let params = {
                    geometry: JSON.stringify(rect),
                    limit: 1
                }

                this.waiting = true;

                //影像查询 TODO
                if(this.dataType == 'imagery' ){
                    this.waiting = false;
                    return;
                };
                let dataType = this.isPrivate ? this.dataType : `public_${this.dataType}` ;
                // console.log(dataType);
                
                axiosInstance.get(`/s/${dataType}/${uid}/query`, {params: params})
                .then((res)=>{

                    let result = res.data;

                    if(result.code == 0){
                        if (result.data == null || !result.data.features.length) {
                            this.waiting = false;
                            this.closeQueryPanel();
                            return;
                        }

                        var elements = result.data.features;
                        var geometryType = result.data.geometryType;

                        this.showQueryAttr(elements[0].attrs, e);
                        this.drawQueryResult(elements, geometryType);

                        this.waiting = false;
                    }else {
                        console.log('查询失败');
                        this.waiting = false;
                    }
                })
                .catch((err)=>{
                    this.waiting = false;
                    throw err;
                });
            },

            drawQueryResult: function(elements, type){

                this.defaultGraphics.clear();
                this.defaultGraphics.bringToTop();

                let g,g0,g1,g2,r,cx,cy;

                switch(type){
                    case 'Point':
                        let point = elements[0].geom;

                        g = new G.Graphic.Point(point, null, {
                            shape: 'circle',
                            outlineColor: '#fff',
                            fillColor: '#000',
                            size:[12, 12]
                        });

                        g.addTo(this.defaultGraphics);
                        break;

                    case 'MultiPoint':
                        for (let j = 0; j <elements[0].geom.m.length; j++){
                            let point = elements[0].geom.m[j];

                            g = new G.Graphic.Point(point, null, {
                                shape: 'circle',
                                outlineColor: '#fff',
                                fillColor: '#000',
                                size:[12, 12]
                            });

                            g.addTo(this.defaultGraphics);
                        }
                        break;

                    case 'Polygon':
                        let polygon = elements[0].geom;
                        g = new G.Graphic.Polygon(polygon,null,{fillColor: '#000', outlineColor: '#fff'});
                        g.addTo(this.defaultGraphics);

                        break;

                    case 'MultiPolygon':
                        for (let j = 0; j <elements[0].geom.m.length; j++){
                            let polygon = elements[0].geom.m[j];
                            g = new G.Graphic.Polygon(polygon,null,{fillColor: '#000', outlineColor: '#fff'});
                            g.addTo(this.defaultGraphics);
                        }
                        break;

                    case 'Polyline':
                        let polyline = elements[0].geom;
                        g = new G.Graphic.Polyline(polyline,null,{lineColor: '#000', lineOpacity: 0.8});
                        g.addTo(this.defaultGraphics);
                        break;

                    case 'MultiPolyline':
                        for (let j = 0; j < elements[0].geom.m.length; j++){
                            let polyline = elements[0].geom.m[j];
                            g = new G.Graphic.Polyline(polyline,null,{lineColor: '#000', lineOpacity: 0.8});
                            g.addTo(this.defaultGraphics);
                        }

                        break;
                }
            },

            showQueryAttr: function(element, event){
                let self = this;
                let arr = [];
                let keys = Object.keys(element).sort();
                let val = '';

                for(var key of keys){
                    val = element[key];

                    if(!val){
                        continue;
                    }

                    arr.push(
                        {key:key, val: element[key]}
                    )

                }

                this.queryResults = arr;
                this.closeQueryPanel();
                this.showResult = true;

                this.$nextTick(() => {
                    let result = this.getDomString();
                    this.htmlLayerMark = this.defaultHtmlLayer.addHtml(result, event.mapX, event.mapY);

                    let closeButton = document.getElementById('closeButton');

                    closeButton.onmousedown = () => {
                        this.closeQueryPanel();
                    };

                    let resultDom = document.getElementById('result');

                    let option = this.isMobel ? 'touchend' : 'mousedown';

                    resultDom.addEventListener(option, (e) => {
                        e.stopPropagation();
                    });

                    // let wheelEvent = (/Firefox/i.test(navigator.userAgent))?"DOMMouseScroll": "mousewheel";
                    // console.log(wheelEvent);
                    resultDom.addEventListener('mousewheel', (e) => {
                        e.stopPropagation();
                    })

                });

            },

            getDomString() {
                let dom = this.$refs.queryResult;

                let tmpNode = document.createElement( "div" );
                tmpNode.appendChild( dom );
                var str = tmpNode.innerHTML;
                tmpNode = null;

                return str;
            },

            toggleSelect: function(){
                this.toggleMapSelect = !this.toggleMapSelect;
            },

            close() {
                this.$emit('close-preview');
            },

            closeMapSelect: function(){
                this.toggleMapSelect = false;
            },

            closeQueryPanel: function(){
                this.defaultHtmlLayer.removeHtml(this.htmlLayerMark);
                this.htmlLayerMark = '';
                this.showResult = false;
                this.defaultGraphics.clear();
            },

            zoomIn: function(){
                if(this.map){
                    this.map.zoomIn();
                }
            },

            zoomOut: function(){
                if(this.map){
                    this.map.zoomOut();
                }
            },

            setBaseMap: function(key) {
                this.currentMap = key;

                let baseMap = this.baseMapList[key];
                var newLayer = new G.Layer.Tile(baseMap.url, {
                    cluster: baseMap.cluster
                });
                let cancelBind = function(){
                    newLayer.unbind('allLoaded');
                };


                newLayer.addTo(this.map);
                newLayer.bringToBottom();
                newLayer.bringUp(1);

                newLayer.bind('allLoaded', ()=>{
                    cancelBind();
                    this.baseMapLayer.remove();
                    this.baseMapLayer = newLayer;
                })
            },

			showGeoreferenceConfirm() {

                let hasQuota = true;

				let promise = this.$confirm('数据尚未进行空间化，马上进行空间化？', '提示', {
					type: 'info',
					showCancelButton: false,
					parent: this.$el,
                    beforeClose: ( action, instance, close ) => {
                        if ( action === 'confirm' ) {
                            instance.confirmButtonLoading = true;
                            instance.confirmButtonText = '处理中...';

                            dashboardAPI.getQuota().then( res => {

                                if ( res.data.code === 0 ) {
                                    let data = res.data.data;

                                    let quota = data.grQuota;
                                    let consume = data.grConsume;

                                    if (quota > 0 && consume >= quota) {
                                        hasQuota = false;
                                    }

                                    close();
                                }

                            })

                        } else {
                            close ();
                        }
                    }
				});

				promise.then(() => {

                    if (!hasQuota) {
                        this.showUpgradeConfirm();
                        return;
                    }

                    this.georeferenceShow = true;

                }).catch((ex) => {

					console.log(ex);

                });

            },

            showUpgradeConfirm() {
                this.$confirm('地址匹配配额已用尽，请前往个人中心 => 方案管理进行升级', '提示', {
                    type: 'info',
                    showCancelButton: false,
                    parent: this.$el,
                    beforeClose: ( action, instance, close ) => {
                        if ( action === 'confirm' ) {
                            close()
                        }
                    }
                })
            },

            /**
             * 
             */
             async initImagery (dataUid, type, bandsCount){
                let index ='0123456789abcdefghijklmnopqrstuvwxyz'.indexOf(dataUid.charAt(2));
                let colorIndex = Math.floor(index%7);
                let colorConfig = [[ '#ffc6c4', '#f4a3a8', '#e38191', '#cc607d', '#ad466c', '#8b3058', '#672044' ],
                                    [ '#fbe6c5', '#f5ba98', '#ee8a82', '#dc7176', '#c8586c', '#9c3f5d', '#70284a' ],
                                    [ '#e4f1e1', '#b4d9cc', '#89c0b6', '#63a6a0', '#448c8a', '#287274', '#0d585f' ],
                                    [ '#f7feae', '#b7e6a5', '#7ccba2', '#46aea0', '#089099', '#00718b', '#045275' ],
                                    [ '#f3cbd3', '#eaa9bd', '#dd88ac', '#ca699d', '#b14d8e', '#91357d', '#6c2167' ],
                                    [ '#eff3ff', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#084594' ],
                                    [ '#d73027', '#fc8d59', '#fee08b', '#ffffbf', '#d9ef8b', '#91cf60', '#1a9850' ]];
                
                let vizConfig = [{
                    "dataUid": dataUid,
                    "dataType": this.isPrivate ? 'private' : 'public',
                    "vizConfig": bandsCount >= 3 ? 
                        {
                            type: "RGB",
                            method: "None",
                            stretch: "histogram-98",
                            opacity: 1,
                            bands: {
                                "red": "b3",
                                "green": "b2",
                                "blue": "b1"
                            }
                        } :
                        {
                            "type": "single-band",
                            "method": "None",
                            stretch: "histogram-98",
                            "bucketBand": "b1",
                            "range": [1, 255],
                            "bucketType": "choropleth",
                            "buckets": [{
                                "value": 255,
                                "color": colorConfig[colorIndex][6]
                            }, {
                                "value": 212.5,
                                "color": colorConfig[colorIndex][5]
                            }, {
                                "value": 170,
                                "color": colorConfig[colorIndex][4]
                            }, {
                                "value": 127.5,
                                "color": colorConfig[colorIndex][3]
                            }, {
                                "value": 85,
                                "color": colorConfig[colorIndex][2]
                            }, {
                                "value": 42.5,
                                "color": colorConfig[colorIndex][1]
                            }, {
                                "value": 1,
                                "color":  colorConfig[colorIndex][0]
                            }]
                        }
                }];

                let params = {
                    configJson: JSON.stringify(vizConfig)
                };

                axiosInstance.post(`/s/imageryviz/config`, qs.stringify( params ))
                .then((res)=>{
                    if(res.data.code !== 0){
                        console.log('可视化失败');
                        return true;
                    }

                    this.vizId = res.data.data.vizId;
                    return true;

                })
                .catch((err)=>{
					console.log(err);
                    throw err;
                });
            }
        },

        watch: {

            vizId: function(newVizId, oldVizId){

                if(this.dataLayer){
                    this.dataLayer.remove();
                }

                let tileUrl = (this.dataType === 'imagery') ? `/s/imageryviz/${newVizId}/{z}/{x}/{y}.png?retina={i}` : `//${window.location.host}/s/dataviz/${newVizId}/{z}/{x}/{y}.png?retina={i}`;
                
                let tileLayer = new G.Layer.Tile(tileUrl, {
                    cluster: ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8'],
                    crossOrigin: "",
                    tileEnlarge: false
                });
                tileLayer.addTo(this.map);
                this.dataLayer = tileLayer;

            },

            previewData: {

                deep: true,
                handler: function(){
                    this.dataLayer.clear();
                    this.defaultGraphics.clear();
                    this.initDataViz();

                    if (this.previewData.extent) {
                        this.map.zoomExtent(JSON.parse(this.previewData.extent), {
                            duration: 1
                        });
                    }
                    
                    this.closeQueryPanel();
                }

            }
        }
    }
</script>

<style lang="scss" rel="stylesheet/scss" scoped>

    @import "common";

    @mixin shadow {
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        border-radius: 2px;
    }

    .map-view-public-data{
       @include absolute (48px, 0px, 0px, 0px);
        z-index: 10;
        font-size: 12px;

        div{
            @include box-sizing(border-box);
        }

        #mapContainer{
            position: relative;
            background-color: $bgWhite;
            height: 100% ;
            width: 100%;
        }

        #mapOverLap{
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
            z-index: 2;
            outline-style: none;
        }

        .map-icon{
            width: 24px;
            height: 24px;
            text-align: center;
            line-height: 24px;
            color: $deepGray;

            &:hover{
                color: $primary;
            }
        }

        .zoom-container{
            width: 24px;
            height: 49px;
            position: absolute;
            top:16px;
            right: 16px;
            cursor: pointer;
            @include shadow;
            background-color: $bgWhite;

            .zoom-split{
                height: 1px;
                width: 16px;
                margin: 0 4px;
                border-top: 1px solid lighten(#ccc, 6%);
            }

        }

        .map-select-container{
            width: 24px;
            height: 24px;
            position: absolute;
            top: 81px;
            right: 16px;
            cursor: pointer;
            outline-style: none;
            background-color: $bgWhite;
            @include shadow;

            .map-select-content{
                @include shadow;
                width: 400px;
                height: 240px;
                position: absolute;
                z-index: 100;
                left: -416px;
                top: -65px;
                background-color: $bgWhite;
                padding: 8px;

                &::before{
                    content:"";
                    display: block;
                    position: absolute;
                    right: -10px;
                    top: 70px;
                    width: 0;
                    height: 0;
                    border-radius: 2px;
                    border-top:8px solid transparent;
                    border-left:10px solid $gray;
                    border-bottom:8px solid transparent;
                }

                &::after{
                    content:"";
                    display: block;
                    position: absolute;
                    right: -9px;
                    top: 70px;
                    width: 0;
                    height: 0;
                    border-radius: 2px;
                    border-top: 8px solid transparent;
                    border-left: 10px solid #fff;
                    border-bottom: 8px solid transparent;
                }
            }

            .base-map-item{

                width: 80px;
                height: 104px;
                margin: 8px 8px 0 8px;
                float: left;

                &.selected{
                    border-radius: 2px;
                }

                .map-thumb{
                    width: 100%;
                    height: 80px;
                    border: 1px solid $bgGray;
                }

                .map-label{
                    height: 18px;
                    line-height: 18px;
                    margin-top: 4px;
                    text-align: center;
                }

                .map-selected {
                    text-align: center;
                    line-height: 80px;
                    color: $primary;
                    display: none;
                }
                &.selected {
                    .map-selected {
                        display: block;
                    }
                }

            }
        }

        .eraser-container{
            width: 24px;
            height: 24px;
            position: absolute;
            top: 113px;
            right: 16px;
            cursor: pointer;
            background-color: $bgWhite;
            @include shadow;
        }

        .result-container{
            width: 260px;
            height: 186px;
            overflow: hidden;
            background-color: #fff;
            box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
            border-radius: 2px;

            .result-title{
                width: 100%;
                height: 36px;
                line-height: 24px;
                padding: 6px 12px;
                font-weight: 400;
                border-bottom: 1px solid $bdGray;
                border-top-right-radius: $bdRadius;
                border-top-left-radius: $bdRadius;

                .title-content{
                    font-size: 12px;
                    float: left;
                }

                .title-close{
                    float: right;
                    cursor: pointer;

                    &:hover{
                        color: $primary;
                    }

                    >i{
                        font-size: 20px;
                    }
                }
            }

            .result-content{
                width: 100%;
                height: 150px;
                font-size: 12px;

                .hide-scroll{
                    // width: 100%;
                    height: 100%;
                    overflow-y: scroll;
                    margin-right: -15px;
                }

                .result-list{
                    overflow: hidden;
                    padding: 8px 12px
                }

                .result-key{
                    color: $gray;
                    padding-right: 3px;
                    overflow: hidden;
                    word-wrap: break-word;
                    @include text-overflow;
                }

                .result-val{
                    text-align: left;
                    font-weight: 500;
                    color: $dark;
                    word-wrap: break-word;
                    overflow: hidden;
                    @include text-overflow;
                }
            }
        }

        .result {

            position: absolute;
            height: 196px;
            bottom: 0;
            left: -130px;

            .arrow{
                height: 10px;

                &::before{
                    content:"";
                    display: block;
                    position: absolute;
                    right: 125px;
                    bottom: 0px;
                    width: 0;
                    height: 0;
                    border-radius: 2px;
                    border-right: 8px solid transparent;
                    border-left: 8px solid transparent;
                    border-top: 10px solid #ababab;
                }

                &::after{
                    content:"";
                    display: block;
                    position: absolute;
                    right: 125px;
                    bottom: 1px;
                    width: 0;
                    height: 0;
                    border-radius: 2px;
                    border-right: 8px solid transparent;
                    border-left: 8px solid transparent;
                    border-top: 10px solid $bgWhite;
                }
            }
        }

    }

    .spin {
        display: inline-block;
        font-size: 12px;
        @include animation(icon-spin 2s infinite linear);
    }

    @include keyframes(icon-spin){
        from {
            @include rotate(0)
        }
        to {
            @include rotate(359)
        }
    }


    .wait-fade-enter-active, .wait-fade-leave-active {
        transition: opacity .5s
    }
    .wait-fade-enter, .wait-fade-leave-active {
        opacity: 0
    }

</style>
